package com.coderMan.generateBeanFromTable.service.impl;

import com.coderMan.generateBeanFromTable.bean.AnnotationBean;
import com.coderMan.generateBeanFromTable.bean.ClazzBean;
import com.coderMan.generateBeanFromTable.service.GenerateBean;
import com.coderMan.generateBeanFromTable.util.GenerateTools;
import com.coderMan.generateBeanFromTable.util.JdbcUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ${fanchunshuai} on 2017-7-11.
 *
 * @version: V1.0
 * @Desc:
 * @Copyright (c) 2017 58到家-版权所有
 */
public class GenerateBeanImpl implements GenerateBean {
    /**
     * 类上的注解描述
     */
    private List<AnnotationBean> classAnnotationList;
    /**
     * id注解描述
     */
    private List<AnnotationBean> idAnnotationList;
    /**
     * 普通注解描述
     */
    private AnnotationBean normal;

    /**
     * 描述bean的公共类
     */
    private ClazzBean clazzBean;





    @Override
    public boolean generateBeanFromTable(ClazzBean clazzBean, String dbConfigPath,String dbName) throws Exception {
        //1.初始化连接db的配置
        JdbcUtils.initDBConnection(dbConfigPath);
        this.setClazzBean(clazzBean);
        //2.查询数据库中所有表中所有的字段信息
        String metaSql = "SELECT TABLE_NAME,COLUMN_NAME,COLUMN_TYPE AS TYPE,COLUMN_COMMENT FROM information_schema.columns WHERE TABLE_SCHEMA = '"+dbName+"'";
        //3.查询数据库中所有表的注释信息
        String tableSql = "SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = '"+dbName+"'";

        Map<String,List<String>> map = JdbcUtils.exeColumnSearchSql(metaSql);

        Map<String,String> tableDescMap = JdbcUtils.exeDBSearchSql(tableSql);

        System.out.println(map.size()+"-------------------");
        try {
            map.forEach((k,v) ->{
                System.out.println("key = "+k);
                /* if(k.equals("csdn_user")){

                }*/
                String className = GenerateTools.genearateBeanName(k,clazzBean.getPreFix(),clazzBean.getSufFix());

                Map<String,String>  map1 = generateVariableList(className,v);
                String head = generateHead(className,k,tableDescMap.get(k));
                System.out.println(head);
                String  varlist = map1.get("varList");
                System.out.println(varlist);
                String getSetList = map1.get("getSetList");
                System.out.println(getSetList);
                String toString = map1.get("toString");
                System.out.println(toString);


                try {
                    writeFile(className,head,varlist,getSetList,toString);
                } catch (IOException e) {
                    e.printStackTrace();
                }

        });
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;

    }

    /**
     * 生成类头部信息
     * @param clazzName
     * @param tableName
     * @return
     */
    private String generateHead(String clazzName,String tableName,String tableDesc){
        StringBuffer buffer = new StringBuffer();
        if(!clazzBean.getPackageName().startsWith("package")){
            buffer.append("package "+clazzBean.getPackageName());
        }else{
            buffer.append(clazzBean.getPackageName());
        }

        if(!buffer.toString().endsWith(";")){
            buffer.append(";");
        }

        buffer.append("\n\n");

        if(clazzBean.getImportClazzList() != null && !clazzBean.getImportClazzList().isEmpty()){
            for (String str:clazzBean.getImportClazzList()){
                if(!str.startsWith("import ")){
                    buffer.append("import "+str);
                }
                if(!str.endsWith(";")){
                    buffer.append(";");
                }
                buffer.append("\n");
            }
        }

        buffer.append("\n\n");


        //生成类注释
        if(clazzBean.getClassDescMap()!= null && clazzBean.getClassDescMap().size() > 0){

            String date = clazzBean.getClassDescMap().get("date");
            String author = clazzBean.getClassDescMap().get("author");
            String version = clazzBean.getClassDescMap().get("version");
            String copy = clazzBean.getClassDescMap().get("copy");

            buffer.append("/**\n" +
                    " * Created by ");

            if(StringUtils.isNotBlank(author)){
                buffer.append(author);
            }

            if(StringUtils.isNotBlank(date)){

                buffer.append(" on "+date+"\n");
            }

            if (StringUtils.isNotBlank(version)){
                buffer.append(" * @version: "+version+"\n");
            }

            if(StringUtils.isNotBlank(tableDesc)){
                buffer.append(" * @desc: "+tableDesc+"\n");
            }
            if (StringUtils.isNotBlank(copy)){
                buffer.append(" * @copyright: "+copy+"\n");
            }
            buffer.append(" */\n");
        }

        //生成类注解
        if(classAnnotationList !=null && !classAnnotationList.isEmpty()){
            for (AnnotationBean bean : classAnnotationList){
                if(StringUtils.isNotBlank(bean.getValueModel())){
                    switch (bean.getValueModel()){
                        case "1":
                            buffer.append("@");
                            buffer.append(bean.getAnnotionName());
                            buffer.append("(");
                            buffer.append(bean.getAttributeName());
                            buffer.append("=\"");
                            //插入自定义类型值
                            buffer.append(bean.getAttributeValue());
                            buffer.append("\")\n");
                            break;
                        case "2":
                            break;
                        case "3":
                            buffer.append("@");
                            buffer.append(bean.getAnnotionName());
                            buffer.append("(");
                            buffer.append(bean.getAttributeName());
                            buffer.append("=\"");
                            //插入数据库名
                            buffer.append(tableName);
                            buffer.append("\")\n");
                            break;
                        case "5":
                            buffer.append("@");
                            buffer.append(bean.getAnnotionName());
                            buffer.append("(");
                            buffer.append(bean.getAttributeName());
                            buffer.append("=\"");
                            //插入bean全限定名
                            String fullClassPath = clazzBean.getPackageName().replace("package","").trim()+"."+clazzName;
                            buffer.append(fullClassPath);
                            buffer.append("\")\n");
                            break;

                    }
                }else{
                    buffer.append("@");
                    buffer.append(bean.getAnnotionName());
                }
            }
        }

        //生成类描述
        buffer.append("public class ");
        buffer.append(clazzName);
        if(StringUtils.isNotBlank(clazzBean.getImplementsName())){
            buffer.append(" implements ").append(clazzBean.getImplementsName());
        }
        if(StringUtils.isNotBlank(clazzBean.getExtendsName())){
            buffer.append(" extends ").append(clazzBean.getExtendsName());
        }
        buffer.append(" {\n");
        return buffer.toString();

    }

    /**
     * 将生成的类写入文件，生成.java文件
     * @param className
     * @param head
     * @param varList
     * @param getSetList
     * @param toString
     * @return
     * @throws IOException
     */
    private boolean writeFile(String className,String head,String varList,String getSetList,String toString) throws IOException {
        String fileName = clazzBean.getClazzPath()+"\\"+className+".java";

        File file = new File(fileName);
        String classInfo = head + varList + getSetList + toString+"\n}";
        FileUtils.writeStringToFile(file,classInfo,"UTF-8");
        return false;
    }

    /**
     * 根据类和字段变量列表生成 变量列表，get/set方法， toString方法
     * @param className
     * @param variableList
     * @return
     */
    private Map<String,String> generateVariableList(String className,List<String> variableList){
        //bean 变量列表
        StringBuffer variable = new StringBuffer();
        StringBuffer getSet = new StringBuffer();
        StringBuffer toString = new StringBuffer("    @Override\n" +
                "    public String toString() { \n        return \""+className+"{\" + ");
        Map<String,String> varMap = new HashMap<>();

        for (int i = 0;i < variableList.size();i ++ ){
            String [] varArray = variableList.get(i).split("-");
            Map<String,String> map = generateOne(varArray);
            variable.append(map.get("varObj"));
            String getSetStr = GenerateTools.generateGetSetMethod(map.get("varType"),map.get("varName"));
            getSet.append(getSetStr);
            if(i == 0){
                toString.append("\""+map.get("varName")+"=\" + "+map.get("varName")+" + \n");
            }else{
                if("String".equals(map.get("varType"))){
                    toString.append("            \", "+map.get("varName")+"='\" + "+ map.get("varName") + " + '\\'' +\n");
                }else{
                    toString.append("            \", "+map.get("varName")+"=\" + "+map.get("varName")+" +\n");
                }
            }

        }

        toString.append("        '}';\n" +
                "    }");
        //System.out.println(toString.toString());
        //System.out.println(getSet.toString());
        //变量列表
        varMap.put("varList",variable.toString());
        //getset列表
        varMap.put("getSetList",getSet.toString());
        //tostring方法
        varMap.put("toString",toString.toString());
        return varMap;
    }

    private Map<String,String> generateOne(String [] varArray){
        Map<String,String> map = new HashMap<>();

        String var ="";
        if(varArray.length == 4){
            var += "    /** " + varArray[3]+" **/ \n";
        }
        StringBuffer annotation = new StringBuffer();
        if("id".equals(varArray[1])){
            if(idAnnotationList !=null && !idAnnotationList.isEmpty()){
                for (AnnotationBean bean : idAnnotationList){
                    if(StringUtils.isNotBlank(bean.getValueModel())){
                        switch (bean.getValueModel()){
                            case "1":
                                annotation.append("    @");
                                annotation.append(bean.getAnnotionName());
                                annotation.append("(");
                                annotation.append(bean.getAttributeName());
                                annotation.append("=\"");
                                //插入自定义类型值
                                annotation.append(bean.getAttributeValue());
                                annotation.append("\")\n");
                                break;
                            case "2":
                                break;
                            case "4":
                                annotation.append("    @");
                                annotation.append(bean.getAnnotionName());
                                annotation.append("(");
                                annotation.append(bean.getAttributeName());
                                annotation.append("=\"");
                                //插入数据库字段
                                annotation.append(varArray[1]);
                                annotation.append("\")\n");
                                break;
                            case "5":
                                break;

                        }
                    }else{
                        annotation.append("    @");
                        annotation.append(bean.getAnnotionName()+"\n");
                    }
                }
            }
        }else{
            if(normal != null && StringUtils.isNotBlank(normal.getValueModel())){
                switch (normal.getValueModel()){
                    case "1":
                        annotation.append("    @");
                        annotation.append(normal.getAnnotionName());
                        annotation.append("(");
                        annotation.append(normal.getAttributeName());
                        annotation.append("=\"");
                        //插入自定义类型值
                        annotation.append(normal.getAttributeValue());
                        annotation.append("\")\n");
                        break;
                    case "2":
                        break;
                    case "4":
                        annotation.append("    @");
                        annotation.append(normal.getAnnotionName());
                        annotation.append("(");
                        annotation.append(normal.getAttributeName());
                        annotation.append("=\"");
                        //插入数据库字段
                        annotation.append(varArray[1]);
                        annotation.append("\")\n");
                        break;
                    case "5":
                        break;

                }
            }else{

                if (normal != null){
                    annotation.append("    @");
                    annotation.append(normal.getAnnotionName()+"\n");
                }
            }
        }
        var += annotation.toString();

        var += "    private  ";
        String varType = GenerateTools.getVarType(varArray[2]);
        var += varType + " ";

        String varName = "";

        if(varArray[1].contains("_")){
            String [] varArr = varArray[1].split("_");
            varName += varArr[0];
            var += varArr[0];

            for (int i = 1 ;i < varArr.length; i++){
                char[] cs= varArr[i].toCharArray();
                cs[0]-=32;
                String v = String.valueOf(cs);
                var += v;
                varName+=v;
            }
        }else{
            var += varArray[1];
            varName = varArray[1];
        }
        var += ";\n\n";
        map.put("varObj",var);
        map.put("varName",varName);
        map.put("varType",varType);

        return map;
    }


    public List<AnnotationBean> getClassAnnotationList() {
        return classAnnotationList;
    }

    public void setClassAnnotationList(List<AnnotationBean> classAnnotationList) {
        this.classAnnotationList = classAnnotationList;
    }

    public List<AnnotationBean> getIdAnnotationList() {
        return idAnnotationList;
    }

    public void setIdAnnotationList(List<AnnotationBean> idAnnotationList) {
        this.idAnnotationList = idAnnotationList;
    }

    public AnnotationBean getNormal() {
        return normal;
    }

    public void setNormal(AnnotationBean normal) {
        this.normal = normal;
    }

    public ClazzBean getClazzBean() {
        return clazzBean;
    }

    public void setClazzBean(ClazzBean clazzBean) {
        this.clazzBean = clazzBean;
    }
}
